/**
 * vue下使用(.vue文件)
 * 读取属性
 * this.$local.get('key')
 * 写入属性
 * this.$local.set('key', Object || Array || any)
 * 移除属性
 * this.$local.remove('key')
 * 是否存在该属性
 * this.$local.has('key')
 *
 * js模块下(.js文件)
 * 引入js包
 * import { Local, Session } from '@/utils/storage'
 *
 * 读取属性
 * Local.get('key')
 * 写入属性
 * Local.set('key', Object || Array || any)
 * 移除属性
 * Local.remove('key')
 * 是否存在该属性
 * Local.has('key')
 *
 * Session用法一致
 *
 */

class Storage {
  get(key) {
    let result = this.drive.getItem(key);
    if (result) {
      let data = deserialize(result);

      // if (Math.floor(+new Date() / 1000) >= data.expires && data.expires !== -1) {
      //   data.data = def
      //   this.remove(key)
      // }

      return data;
    } else {
      return undefined;
    }
  }

  set(key, val, expires = -1) {
    try {
      if (val === undefined) {
        return this.remove(key);
      }

      // if (typeof expires === 'number' && expires >= 0) {
      //   expires = Math.floor(+new Date() / 1000) + expires
      // } else {
      //   expires = -1
      // }

      // let data = {
      //   data: val,
      //   expires
      // }

      this.drive.setItem(key, serialize(val));
    } catch (e) {
      console.log("Local Storage is full, Please empty data");
    }
    return val;
  }

  has(key) {
    return this.get(key) !== undefined;
  }

  remove(key) {
    this.drive.removeItem(key);
  }

  clear() {
    this.drive.clear();
  }

  get size() {
    let total = 0;
    for (let x in this.drive) {
      // Value is multiplied by 2 due to data being stored in `utf-16` format, which requires twice the space.
      let amount = this.drive[x].length * 2;
      if (
        !isNaN(amount) &&
        Object.prototype.hasOwnProperty.call(this.drive, x)
      ) {
        total += amount;
      }
    }
    return total.toFixed(2);
  }
}

class LocalStorage extends Storage {
  constructor() {
    super();
    this.drive = window.localStorage;
  }
}

class SessionStorage extends Storage {
  constructor() {
    super();
    this.drive = window.sessionStorage;
  }
}

export const Local = new LocalStorage();
export const Session = new SessionStorage();

function serialize(val) {
  return JSON.stringify(val);
}

function deserialize(val) {
  if (typeof val !== "string") {
    return undefined;
  }
  try {
    return JSON.parse(val);
  } catch (e) {
    return val || undefined;
  }
}
